#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << PAGE_SHIFT)
-#define round_pgup(x) (((x) + PAGE_SIZE-1) & ~ (PAGE_SIZE-1))
- int npte_pages = 1 + (round_pgup(nr_pages * 4) / PAGE_SIZE);
-
- /* We don't map pte pages and the top 64k -- XXX: this could be a problem */
if ((vector = (Bit8u *) xc_map_foreign_batch(xc_handle, domid,
PROT_READ|PROT_WRITE,
page_array,
- nr_pages - npte_pages - 16)) == 0) {
+ nr_pages - 1)) == 0) {
BX_ERROR(("Could not map guest physical"));
return;
}
- BX_MEM_THIS dma_limit = (nr_pages - npte_pages - 16) << PAGE_SHIFT;
+ BX_MEM_THIS dma_limit = (nr_pages - 1) << PAGE_SHIFT;
BX_INFO(("DMA limit: %lx", BX_MEM_THIS dma_limit));
shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
struct mem_map;
int xc_vmx_build(int xc_handle,
u32 domid,
+ int memsize,
const char *image_name,
struct mem_map *memmap,
const char *ramdisk_name,
struct domain_setup_info *dsi);
static int setup_guestos(int xc_handle,
- u32 dom,
+ u32 dom, int memsize,
char *image, unsigned long image_size,
gzFile initrd_gfd, unsigned long initrd_len,
unsigned long nr_pages,
* read-only). We have a pair of simultaneous equations in two unknowns,
* which we solve by exhaustive search.
*/
- nr_pt_pages = 1 + (nr_pages >> (PAGE_SHIFT - 2));
vboot_params_start = LINUX_BOOT_PARAMS_ADDR;
vboot_params_end = vboot_params_start + PAGE_SIZE;
vboot_gdt_start = vboot_params_end;
vboot_gdt_end = vboot_gdt_start + PAGE_SIZE;
- v_end = nr_pages << PAGE_SHIFT;
- vpt_end = v_end - (16 << PAGE_SHIFT); /* leaving the top 64k untouched */
- vpt_start = vpt_end - (nr_pt_pages << PAGE_SHIFT);
- vinitrd_end = vpt_start;
+
+ v_end = memsize << 20;
+ vinitrd_end = v_end - PAGE_SIZE; /* leaving the top 4k untouched for IO requests page use */
vinitrd_start = vinitrd_end - initrd_len;
vinitrd_start = vinitrd_start & (~(PAGE_SIZE - 1));
if(initrd_len == 0)
vinitrd_start = vinitrd_end = 0;
+ nr_pt_pages = 1 + ((memsize + 3) >> 2);
+ vpt_start = v_end;
+ vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE);
+
printf("VIRTUAL MEMORY ARRANGEMENT:\n"
" Boot_params: %08lx->%08lx\n"
" boot_gdt: %08lx->%08lx\n"
}
*vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
- if ( (count >= ((vpt_start-dsi.v_start)>>PAGE_SHIFT)) &&
- (count < ((vpt_end -dsi.v_start)>>PAGE_SHIFT)) )
- *vl1e &= ~_PAGE_RW;
vl1e++;
}
munmap(vl1tab, PAGE_SIZE);
boot_paramsp->initrd_start = vinitrd_start;
boot_paramsp->initrd_size = initrd_len;
- i = (nr_pages >> (PAGE_SHIFT - 10)) - (1 << 10) - 4;
+ i = ((memsize - 1) << 10) - 4;
boot_paramsp->alt_mem_k = i; /* alt_mem_k */
boot_paramsp->screen.overlap.ext_mem_k = i & 0xFFFF; /* ext_mem_k */
int xc_vmx_build(int xc_handle,
u32 domid,
+ int memsize,
const char *image_name,
struct mem_map *mem_mapp,
const char *ramdisk_name,
goto error_out;
}
- if ( setup_guestos(xc_handle, domid, image, image_size,
+ if ( setup_guestos(xc_handle, domid, memsize, image, image_size,
initrd_gfd, initrd_size, nr_pages,
ctxt, cmdline,
op.u.getdomaininfo.shared_info_frame,
PyObject *memmap;
int control_evtchn, flags = 0;
int numItems, i;
+ int memsize;
struct mem_map mem_map;
- static char *kwd_list[] = { "dom", "control_evtchn",
+ static char *kwd_list[] = { "dom", "control_evtchn",
+ "memsize",
"image", "memmap",
"ramdisk", "cmdline", "flags",
NULL };
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iisO!|ssi", kwd_list,
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiisO!|ssi", kwd_list,
&dom, &control_evtchn,
+ &memsize,
&image, &PyList_Type, &memmap,
&ramdisk, &cmdline, &flags) )
return NULL;
mem_map.map[i-1].caching_attr = lf4;
}
- if ( xc_vmx_build(xc->xc_handle, dom, image, &mem_map,
+ if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, &mem_map,
ramdisk, cmdline, control_evtchn, flags) != 0 )
return PyErr_SetFromErrno(xc_error);
self.restart_time = None
self.console_port = None
self.savedinfo = None
+ self.image_handler = None
self.is_vmx = 0
self.vcpus = 1
except:
raise VmError('invalid vcpus value')
+ self.find_image_handler()
self.init_domain()
self.configure_console()
self.configure_backends()
raise
return deferred
- def construct_image(self):
+ def find_image_handler(self):
"""Construct the boot image for the domain.
@return vm
image_name = sxp.name(image)
if image_name is None:
raise VmError('missing image name')
+ if image_name == "vmx":
+ self.is_vmx = 1
image_handler = get_image_handler(image_name)
if image_handler is None:
raise VmError('unknown image type: ' + image_name)
- image_handler(self, image)
+ self.image_handler = image_handler
+ return self
+
+ def construct_image(self):
+ image = sxp.child_value(self.config, 'image')
+ self.image_handler(self, image)
return self
def config_devices(self, name):
except:
raise VmError('invalid cpu')
cpu_weight = self.cpu_weight
- dom = xc.domain_create(dom= dom, mem_kb= memory * 1024,
+ memory = memory * 1024 + self.pgtable_size(memory)
+ dom = xc.domain_create(dom= dom, mem_kb= memory,
cpu= cpu, cpu_weight= cpu_weight)
if dom <= 0:
raise VmError('Creating domain failed: name=%s memory=%d'
err = buildfn(dom = dom,
image = kernel,
control_evtchn = 0,
+ memsize = self.memory,
memmap = memmap,
cmdline = cmdline,
ramdisk = ramdisk,
d.addErrback(dlist_err)
return d
+ def pgtable_size(self, memory):
+ """Return the size of memory needed for 1:1 page tables for physical
+ mode.
+
+ @param memory: size in MB
+ @return size in KB
+ """
+ if self.is_vmx:
+ # Logic x86-32 specific.
+ # 1 page for the PGD + 1 pte page for 4MB of memory (rounded)
+ return (1 + ((memory + 3) >> 2)) * 4
+ return 0
def vm_image_linux(vm, image):
"""Create a VM for a linux image.
from xen.util.memmap import memmap_parse
memmap = memmap_parse(memmap)
vm.create_domain("vmx", kernel, ramdisk, cmdline, memmap)
- vm.is_vmx = 1
return vm
def vm_dev_vif(vm, val, index, change=0):